package search;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;

public class StudentCreditManagementSystem {

    // 存储学生信息的列表
    private static List<Student> students = new ArrayList<>();

    // 存储课程与对应学分的映射
    private static Map<String, Integer> courseCredits = new HashMap<>();

    // 将百分制成绩转换为字母分制的方法
    private static String convertToLetterGrade(double score) {
        if (score >= 90) {
            return "A";
        } else if (score >= 80) {
            return "B";
        } else if (score >= 70) {
            return "C";
        } else if (score >= 60) {
            return "D";
        } else {
            return "F";
        }

        // 可添加以下注释用于提醒和简单验证逻辑
        // 这里假设成绩是按照标准的百分制划分等级，
        // 如果后续发现等级划分与实际需求不符，可在此处修改逻辑。
        // 例如，如果需要更精细的划分，如A+、A-等，可以扩展此方法。
    }

    // 计算学生GPA的方法
    private static double calculateGPA(Student student) {
        double totalGradePoints = 0;
        int totalCredits = 0;

        for (CourseEnrollment enrollment : student.getCourseEnrollments()) {
            String letterGrade = enrollment.getLetterGrade();
            int credit = courseCredits.get(enrollment.getCourseName());

            // 明确不同字母分制对应的绩点计算
            double gradePoint = 0;
            if ("A".equals(letterGrade)) {
                gradePoint = 4.0;
            } else if ("A-".equals(letterGrade)) {
                gradePoint = 3.7;
            } else if ("B+".equals(letterGrade)) {
                gradePoint = 3.3;
            } else if ("B".equals(letterGrade)) {
                gradePoint = 3.0;
            } else if ("B-".equals(letterGrade)) {
                gradePoint = 2.7;
            } else if ("C+".equals(letterGrade)) {
                gradePoint = 2.3;
            } else if ("C".equals(letterGrade)) {
                gradePoint = 2.0;
            } else if ("C-".equals(letterGrade)) {
                gradePoint = 1.7;
            } else if ("D+".equals(letterGrade)) {
                gradePoint = 1.3;
            } else if ("D".equals(letterGrade)) {
                gradePoint = 1.0;
            } else if ("D-".equals(letterGrade)) {
                gradePoint = 0.7;
            } else if ("F".equals(letterGrade)) {
                gradePoint = 0;
            }

            totalGradePoints += gradePoint * credit;
            totalCredits += credit;
        }

        if (totalCredits == 0) {
            return 0;
        }

        return totalGradePoints / totalCredits;
    }

    // 从文本文件导入学生成绩的方法
    private static void importStudentGradesFromFile(String filePath) {
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            while ((line = reader.readLine())!= null) {
                String[] parts = line.split(",");
                if (parts.length >= 3) {
                    String studentName = parts[0];
                    String courseName = parts[1];
                    double score;
                    try {
                        score = Double.parseDouble(parts[2]);
                        // 新增：验证成绩是否在百分制合理范围内
                        if (score < 0 || score > 100) {
                            System.out.println("成绩应在0到100之间，该行数据有误：" + line);
                            continue;
                        }

                        // 新增：验证课程是否已在课程学分映射中定义
                        if (!courseCredits.containsKey(courseName)) {
                            System.out.println("该课程未在系统中定义学分，该行数据有误：" + line);
                            continue;
                        }

                        Student student = findStudentByName(studentName);
                        if (student == null) {
                            student = new Student(studentName);
                            students.add(student);
                        }

                        CourseEnrollment enrollment = new CourseEnrollment(courseName, score);
                        student.addCourseEnrollment(enrollment);

                        // 新增：验证是否成功添加课程选课记录
                        if (!student.getCourseEnrollments().contains(enrollment)) {
                            System.out.println("添加课程选课记录失败，请检查代码！");
                        }
                    } catch (NumberFormatException e) {
                    System.out.println("成绩格式不正确，该行数据有误：" + line);
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 根据学生姓名查找学生对象的方法
    private static Student findStudentByName(String studentName) {
        for (Student student : students) {
            if (student.getName().equals(studentName)) {
                return student;
            }
        }
        return null;
    }

    // 导出学生选科记录及其成绩到文本文件的方法
    private static void exportStudentRecordsToFile(String filePath) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath))) {
            for (Student student : students) {
                for (CourseEnrollment enrollment : student.getCourseEnrollments()) {
                    writer.write(student.getName() + "," + enrollment.getCourseName() + "," + enrollment.getScore() + "\n");
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 定义课程学分的方法
    private static void defineCourseCredit(String courseName) {
        Scanner scanner = new Scanner(System.in);
        System.out.print("请输入课程 " + courseName + " 的学分：");
        int credit;
        try {
            credit = scanner.nextInt();
            courseCredits.put(courseName, credit);
            System.out.println("课程 " + courseName + " 的学分已成功定义为 " + credit);
        } catch (NumberFormatException e) {
            System.out.println("输入的学分格式不正确，请重新输入！");
            defineCourseCredit(courseName);
        } finally {
            scanner.close();
        }
    }

    // 学生类
    static class Student {
        private String name;
        private List<CourseEnrollment> courseEnrollments = new ArrayList<>();

        public Student(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }

        public List<CourseEnrollment> getCourseEnrollments() {
            return courseEnrollments;
        }

        public void addCourseEnrollment(CourseEnrollment enrollment) {
            courseEnrollments.add(enrollment);
        }
    }

    // 课程选课记录类
    static class CourseEnrollment {
        private String courseName;
        private double score;
        private String letterGrade;

        public CourseEnrollment(String courseName, double score) {
            this.courseName = courseName;
            this.score = score;
            this.letterGrade = convertToLetterGrade(score);
        }

        public String getCourseName() {
            return courseName;
        }

        public double getScore() {
            return score;
        }

        public String getLetterGrade() {
            return letterGrade;
        }
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 初始化一些课程与学分的映射
        courseCredits.put("Math", 3);
        courseCredits.put("English", 3);
        courseCredits.put("Science", 4);

        System.out.println("欢迎使用学生学分管理系统！");
        System.out.println("1. 从文本文件导入学生成绩");
        System.out.println("2. 录入新学生成绩");
        System.out.println("3. 查询学生GPA");
        System.out.println("4. 导出学生选科记录及其成绩");
        System.out.println("5. 退出");

        while (true) {
            System.out.print("请选择操作：");
            int choice = scanner.nextInt();

            switch (choice) {
                case 1:
                    System.out.print("请输入文件路径：");
                    String filePath = scanner.next();
                    importStudentGradesFromFile(filePath);
                    break;
                case 2:
                    System.out.print("请输入学生姓名：");
                    String studentName = scanner.next();
                    Student student = findStudentByName(studentName);
                    if (student == null) {
                    student = new Student(studentName);
                    students.add(student);
                    }

                    System.out.print("请输入课程名称：");
                    String courseName = scanner.next();

                    // 新增：验证课程是否已在课程学分映射中定义
                    if (!courseCredits.containsKey(courseName)) {
                        System.out.println("该课程未在系统中定义学分，请先定义课程学分！");
                        defineCourseCredit(courseName);
                        continue;
                    }

                    System.out.print("请输入成绩：");
                    double score;
                    try {
                        score = Double.parseDouble(scanner.next());
                        // 新增：验证成绩是否在百分制合理范围内
                        if (score < 0 || score > 100) {
                            System.out.println("成绩应在0到100之间，请重新输入！");
                            continue;
                        }
                    } catch (NumberFormatException e) {
                        System.out.println("输入的成绩格式不正确，请重新输入！");
                        continue;
                    }

                    CourseEnrollment enrollment = new CourseEnrollment(courseName, score);
                    student.addCourseEnrollment(enrollment);

                    // 新增：验证是否成功添加课程选课记录
                    if (!student.getCourseEnrollments().contains(enrollment)) {
                        System.out.println("添加课程选课记录失败，请检查代码！");
                    }
                    break;
                case 3:
                    System.out.print("请输入学生姓名：");
                    studentName = scanner.next();
                    student = findStudentByName(studentName);
                    if (student!= null) {
                        double gpa = calculateGPA(student);
                        System.out.println(studentName + "的GPA为：" + gpa);
                    } else {
                        System.out.println("未找到该学生！");
                    }
                    break;
                case 4:
                    System.out.print("请输入文件路径：");
                    String exportFilePath = scanner.next();
                    exportStudentRecordsToFile(exportFilePath);
                    break;
                case 5:
                    scanner.close();
                    System.exit(0);
                default:
                    System.out.println("无效的选择，请重新输入！");
            }
        }
    }
}